home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / progutil / stdwin.zoo / test / bits.c next >
Encoding:
C/C++ Source or Header  |  1989-10-19  |  2.6 KB  |  152 lines

  1. /* Here's a very simple bitmap editor.
  2.    A window shows a magnified 64x64 bitmap
  3.    which you can edit by clicking the mouse.
  4.    Clicking on a bit that's off turns it on,
  5.    clicking on one that's on turns it off.
  6.    Drag the mouse to set or clear more bits.
  7.    Additional facilities like saving to a file
  8.    are left as exercises for the reader. */
  9.  
  10. #include "stdwin.h"
  11. long _stksize = 16384L;
  12.  
  13. /* Bitmap dimensions */
  14.  
  15. #define WIDTH 64
  16. #define HEIGHT 64
  17.  
  18. /* The bitmap */
  19.  
  20. char bit[WIDTH][HEIGHT];
  21.  
  22. /* Magnification factors.
  23.    (Should really be calculated from screen dimensions). */
  24.  
  25. int xscale= 5;
  26. int yscale= 5;
  27.  
  28. /* The window */
  29.  
  30. WINDOW *win;
  31.  
  32. /* Main program */
  33.  
  34. main(argc, argv)
  35.     int argc;
  36.     char **argv;
  37. {
  38.     winitnew(&argc, &argv);
  39.     setup();
  40.     mainloop();
  41.     wdone();
  42.     exit(0);
  43. }
  44.  
  45. /* Create the window */
  46.  
  47. setup()
  48. {
  49.     extern void drawproc(); /* Forward */
  50.     
  51.     wsetdefwinsize(WIDTH*xscale, HEIGHT*yscale);
  52.     win= wopen("Bitmap Editor Demo", drawproc);
  53.     wsetdocsize(win, WIDTH*xscale, HEIGHT*yscale);
  54. }
  55.  
  56. /* Main event loop */
  57.  
  58. mainloop()
  59. {
  60.     int value= 0;
  61.     
  62.     for (;;) {
  63.         EVENT e;
  64.         
  65.         wgetevent(&e);
  66.         
  67.         switch (e.type) {
  68.         
  69.         case WE_MOUSE_DOWN:
  70.             value= !getbit(e.u.where.h/xscale, e.u.where.v/yscale);
  71.             /* Fall through to next cases */
  72.         case WE_MOUSE_MOVE:
  73.         case WE_MOUSE_UP:
  74.             setbit(e.u.where.h/xscale, e.u.where.v/yscale, value);
  75.             break;
  76.         
  77.         case WE_COMMAND:
  78.             switch (e.u.command) {
  79.             case WC_CLOSE:
  80.             case WC_CANCEL:
  81.                 return;
  82.             }
  83.         
  84.         }
  85.     }
  86. }
  87.  
  88. /* Draw procedure */
  89.  
  90. void
  91. drawproc(win, left, top, right, bottom)
  92.     WINDOW *win;
  93. {
  94. #ifdef UNOPTIMIZED
  95.     int h, v;
  96.  
  97.     for (v= top/yscale; v*yscale < bottom; ++v) {
  98.         for (h= left/xscale; h*xscale < right; ++h) {
  99.             if (getbit(h, v))
  100.                 wpaint(h*xscale, v*yscale,
  101.                     (h+1)*xscale, (v+1)*yscale);
  102.         }
  103.     }
  104. #else
  105.     int h, v;
  106.     int start;
  107.  
  108.     for (v= top/yscale; v*yscale < bottom; ++v) {
  109.         start = -1;
  110.         for (h= left/xscale; h*xscale < right; ++h) {
  111.             if (getbit(h, v)) {
  112.                 if (start == -1)
  113.                     start = h;
  114.             } else {
  115.                 if (start != -1) {
  116.                     wpaint(start*xscale, v*yscale,
  117.                         h*xscale, (v+1)*yscale);
  118.                     start = -1;
  119.                 }
  120.             }
  121.         }
  122.         if (start != -1)
  123.             wpaint(start*xscale, v*yscale, h*xscale, (v+1)*yscale);
  124.     }
  125. #endif
  126. }
  127.  
  128. /* Macro to test for bit coordinates in range */
  129.  
  130. #define INRANGE(h, v) ((v) >= 0 && (v) < HEIGHT && (h) >= 0 && (h) < WIDTH)
  131.  
  132. /* Return a bit's value; return 0 if outside range */
  133.  
  134. int
  135. getbit(h, v)
  136. {
  137.     if (INRANGE(h, v))
  138.         return bit[h][v];
  139.     else
  140.         return 0;
  141. }
  142.  
  143. /* Change a bit's value (if in range) and arrange for it to be drawn. */
  144.  
  145. setbit(h, v, value)
  146. {
  147.     if (INRANGE(h, v) && bit[h][v] != value) {
  148.         bit[h][v]= value;
  149.         wchange(win, h*xscale, v*yscale, (h+1)*xscale, (v+1)*yscale);
  150.     }
  151. }
  152.